/*
 * Copyright (c) 2023 Cshoo Org. All Rights Reserved.
 */

package org.cshoo.tattoo.datacenter.domain.service;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.IteratorUtils;
import org.cshoo.tattoo.datacenter.domain.bo.ConfigBo;
import org.cshoo.tattoo.datacenter.domain.po.Config;
import org.cshoo.tattoo.datacenter.domain.po.ConfigItem;
import org.cshoo.tattoo.datacenter.domain.repository.IConfigItemRepository;
import org.cshoo.tattoo.datacenter.domain.repository.IConfigRepository;
import org.cshoo.tattoo.embed.infra.entity.PageQueryEntity;
import org.cshoo.tattoo.embed.infra.exception.ValidateException;
import org.cshoo.tattoo.embed.infra.utils.UserUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author 杨翼
 * @since 1.0
 */
@Service
@Slf4j
public class ConfigService {

    @Resource
    private IConfigRepository configRepository;

    @Resource
    private IConfigItemRepository configItemRepository;

    /**
     * 判断此编号是否存在
     *
     * @param code config编号
     * @return 判断结果
     */
    public boolean checkConfigCodeExists(String code) {
        Config config = configRepository.findByCode(code);
        log.info("config:{}", config);
        return !Objects.isNull(config);
    }

    /**
     * 判断此编号是否存在
     *
     * @param configId    config id
     * @param environment 环境
     * @return 判断结果
     */
    public boolean checkConfigItemEnvironmentExists(Long configId, String environment) {
        ConfigItem configItem = configItemRepository.findByConfigIdAndEnvironment(configId, environment);
        log.info("configItem:{}", configItem);
        return !Objects.isNull(configItem);
    }

    /**
     * 添加一个config
     *
     * @param config 添加config
     */
    public void addConfig(Config config) {
        configRepository.save(config);
    }

    /**
     * 修改一个config
     *
     * @param config 修改config信息
     */
    public void updateConfig(Config config) {
        config.setLastModifiedBy(UserUtils.getUser().getUsername());
        config.setLastModifiedDate(new Date());
        configRepository.updateConfig(config);
    }

    /**
     * 删除一个config
     *
     * @param id id
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteConfig(Long id) {
        log.info("id:{}", id);
        configItemRepository.deleteByConfigId(id);
        configRepository.deleteById(id);
    }

    /**
     * 删除一个config item
     *
     * @param id id
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteConfigItem(Long id) {
        configItemRepository.deleteById(id);
    }

    /**
     * 查询config列表
     *
     * @return config列表
     */
    @SuppressWarnings("unchecked")
    public List<Config> queryConfigs() {
        Iterable<Config> configIterable = configRepository.findAll();
        return IteratorUtils.toList(configIterable.iterator());
    }

    /**
     * 分页查询
     *
     * @param configPageReq 分页查询对象
     * @return 分页查询结果
     */
    public Page<Config> queryConfigs(PageQueryEntity<String> configPageReq) {
        PageRequest pageRequest = PageRequest.of(configPageReq.getPageNumber(), configPageReq.getPageSize());
        String keyword = configPageReq.getQuery();
        return configRepository.findConfig(keyword, pageRequest);
    }

    /**
     * 根据configId查询item
     *
     * @param configId configId
     * @return item列表
     */
    public List<ConfigItem> queryConfigItems(Long configId) {
        log.info("configId:{}", configId);
        return configItemRepository.findByConfigIdOrderByCreatedDate(configId);
    }

    /**
     * 根据code和configId查看是否存在configItem
     *
     * @param configId configId
     * @return 查看存在结果
     */
    public boolean checkConfigItemCodeExists(String code, Long configId) {
        log.info("code:{},configId:{}", code, configId);
        return !Objects.isNull(configItemRepository.findByConfigId(configId));
    }

    /**
     * 添加一个config项
     *
     * @param configItem 添加config项
     */
    public void addConfigItem(ConfigItem configItem) throws Exception {
        Long configId = configItem.getConfigId();
        String environment = configItem.getEnvironment();
        ConfigItem checkConfigItem = configItemRepository.findByConfigIdAndEnvironment(configId, environment);
        if (Objects.nonNull(checkConfigItem)) {
            throw new ValidateException("Config Item Duplicate");
        }
        configItemRepository.save(configItem);
    }

    /**
     * 修改一个config项
     *
     * @param configItem 修改config项
     */
    public void updateConfigItem(ConfigItem configItem) {
        configItem.setLastModifiedBy(UserUtils.getUser().getUsername());
        configItem.setLastModifiedDate(new Date());
        configItemRepository.updateConfigItem(configItem);
    }

    /**
     * 查询单个config
     *
     * @param code 编号
     * @return 单个config对象
     */
    public ConfigBo querySingleConfig(String code) {
        Config config = configRepository.findByCode(code);
        List<ConfigItem> configItems = configItemRepository.findByConfigId(config.getId());
        ConfigBo configBo = new ConfigBo();
        BeanUtils.copyProperties(config, configBo);
        configBo.setConfigItems(configItems);
        return configBo;
    }
}
